from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from typing import Callable, Set, Optional
from .token_service import TokenService
from utils.log_utils import logger

# 存储不需要验证 token 的路由
UNPROTECTED_ROUTES: Set[str] = {
	"/docs",
	"/openapi.json",
	"/api/user/login",
	"/api/user/register-user",
	"/user/register-user",
	"/user/login",
	"/test/send-email",
	"/comments/list",
	"/comments/create",
	"/public",
}


async def token_auth_middleware(request: Request, call_next):
	# 打印请求方法
	# logger.info(f"请求方法: {request.method}")
	# print(f"请求方法: {request.method}")

	# GET方法直接放行
	if request.method.lower() == "get":
		return await call_next(request)

	# 检查当前路径是否在不需要验证的路由中
	if request.url.path in UNPROTECTED_ROUTES:
		return await call_next(request)

	# print("不是放行路径",request.url.path)
	# 获取 token
	auth_header = request.headers.get("Authorization")
	if not auth_header:
		print("未提供认证token凭证",request.headers)
		return JSONResponse(
			status_code=401,
			content={"detail": "未提供认证凭证"}
		)
	# 验证 Bearer Token 格式
	parts = auth_header.split(" ")
	if len(parts) != 2 or parts[0].lower() != "bearer":
		print("auth_header:",auth_header)
		return JSONResponse(
			status_code=401,
			content={"detail": "认证凭证格式错误"}
		)
	token = parts[1]
	"""
	不要相信token上的过期时间，要从redis判断
	"""
	payload = TokenService.verify_token(token)
	user_id = payload.get("sub")
	# print("user_id:",f'FUser.{user_id}')
	redis_cache =await request.app.state.redis.get(f'FUser.{user_id}')
	# print("redis_cache:",redis_cache)
	if not redis_cache:
		return JSONResponse(
			status_code=401,
			content={"detail": "认证凭证已过期"}
		)
	# 校验token并判断是否需要刷新 取消刷新，因为用的是别的应用
	# try:
	# 	# 判断是否需要刷新token
	# 	if TokenService.should_refresh_token(token):
	# 		# 生成新token
	# 		new_access_token, _ = TokenService.create_tokens(user_id=user_id, payload=payload)
	# 		redis_key = f'FUser.{user_id}'
	# 		# 刷新redis缓存
	# 		if hasattr(request.app.state, 'redis'):
	# 			await request.app.state.redis.set(redis_key, new_access_token,ex=7200)
	# 			logger.info(f"无感刷新token并更新redis缓存: {redis_key}")
	# 			print(f"无感刷新token并更新redis缓存: {redis_key}")
	#
	# except Exception as e:
	# 	return JSONResponse(
	# 		status_code=401,
	# 		content={"detail": f"无效的认证凭证: {str(e)}"}
	# 	)
	
	# 将验证后的 token 存入请求状态中，供后续使用
	request.state.token = token
	request.state.userId = user_id
	
	return await call_next(request)